using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using Jonathan.SharpDB;
using System.Threading;
using System.Collections;
using System.Text;

namespace Jonathan
{
	/// <summary>
	/// Adds the search results to the display.
	/// </summary>
    public delegate void DelSetSearchResult ();

	/// <summary>
	/// Class to search through the material in Jonathan.
	/// </summary>
    public partial class ctrlSearch : Tabber.TabberPage, IWebberHost
    {
        private frmMain m_FormMain;
        private string m_DBFile;
        private string m_Type;
        private string m_SearchType;
        private DelSetSearchResult m_SetSearchResults;
        private bool m_Loaded;
        private List<string[]> m_SearchResults;
        private string m_ResultsHTML;
        private int m_ResultCount;

        #region - Constructor - 

        /// <summary>
        /// Creates a new Search Control...
        /// </summary>
        /// <param name="main"></param>
        public ctrlSearch (frmMain main, string type)
            : base("Search")
        {
            this.m_Loaded = false;
            this.m_FormMain = main;
			InitializeComponent();
			this._WebSearch.SetupWebber(main, this);

            this.m_ResultsHTML = "";
            this.m_ResultCount = 0;
            this.Load += new EventHandler(ctrlSearch_Load);
            this.Resize += new EventHandler(ctrlSearch_Resize);
            this.SetEmptyResults();

            if (this.m_FormMain != null)
            {
                this.m_SearchType = type;
                this.m_cmbVersion.DropDownStyle = ComboBoxStyle.DropDownList;
                this.m_SetSearchResults = new DelSetSearchResult(this.SetSearchResults);

                if (type != Common.TYPE_PASSAGE)
                {
                    // Add Bibles
                    foreach (cJData.icDBInfo dbTemp in this.m_FormMain.ProgramData.BibleDatabases)
                    {
                        this.m_cmbVersion.Items.Add(dbTemp.Name);
                    }
                    // Add Other Books
                    foreach (cJData.icDBInfo dbTemp in this.m_FormMain.ProgramData.OtherDatabases)
                    {
                        this.m_cmbVersion.Items.Add(dbTemp.Name);
                    }
                    // Add Reference
                    if (this.m_FormMain.ProgramData.ReferenceDatabases.Count > 0)
                    {
                        this.m_cmbVersion.Items.Add("Search " + Common.TYPE_REFERENCE);
                    }

                    if (type == Common.TYPE_REFERENCE)
                    {
                        this.m_cmbVersion.SelectedIndex = this.m_cmbVersion.Items.Count - 1;
                    }
                    else if (type == Common.TYPE_BIBLE)
                    {
                        this.m_cmbVersion.SelectedIndex = this.m_cmbVersion.Items.IndexOf(this.m_FormMain.ProgramData.DefaultBible);
                        this.m_DBFile = this.m_FormMain.DefaultBibleFile;
                        UpdateBookList();
                    }
                }
                else
                {
                    this.grpCriteria.Visible = false;
                    this.grpRange.Width = this.grpRange.Width + this.grpCriteria.Width + (this.grpRange.Left - this.grpCriteria.Right);
                    this.grpRange.Left = grpCriteria.Left;
                    this.rdoNewTest.Visible = false;
                    this.rdoOldTest.Visible = false;
                    this.rdoNone.Checked = true;
                    this.m_Type = Common.TYPE_PASSAGE;
                    foreach (cJData.icDBInfo dbTemp in this.m_FormMain.ProgramData.BibleDatabases)
                    {
                        this.clbBooks.Items.Add(dbTemp.Name, false);
                    }
                    int index = this.clbBooks.Items.IndexOf(this.m_FormMain.ProgramData.DefaultBible);
                    this.clbBooks.SetItemChecked(index, true);
                }

                this.m_cmbSearch.KeyDown += new KeyEventHandler(SearchText_KeyDown);
                this.m_cmbSearch.Focus();
                this.SetTabText();
                this.UpdateFont();
                this._Working.BringToFront();
            }
        }

        void ctrlSearch_Resize (object sender, EventArgs e)
        {
            this._Working.Top = this._WebSearch.Bottom - this._Working.Height - 3;
            this._Working.Left = (this.Width / 2) - (this._Working.Width / 2);
        }

        void ctrlSearch_Load (object sender, EventArgs e)
        {
            if (m_Loaded)
                this.Search();
            else
            {
                this.m_Loaded = true;
                this._Working.Visible = false;
            }
        }

        #endregion

        #region -= Get Book Type =-

        /// <summary>
        /// Gets the Type of Book...
        /// </summary>
        /// <param name="path"></param>
        private void GetBookType ()
        {
            // Create a Query...
            Query q = new Query(QueryType.SELECT, Common.TABLE_INFO);
            q.SELECT("Type");

            // Run Query...
            Database db = new Database(this.m_DBFile);
            db.RunQuery(q);
            this.m_Type = q.Results.GetFieldString(0, 0);
        }

        #endregion

        #region - Update Book List -

        /// <summary>
        /// Updates the list of books to search in...
        /// </summary>
        private void UpdateBookList ()
        {
            this.GetBookType();
            if (this.m_Type == Common.TYPE_OTHER)
            {
                this.rdoNewTest.Enabled = false;
                this.rdoOldTest.Enabled = false;
            }
            else if (this.m_Type == Common.TYPE_BIBLE)
            {
                this.rdoNewTest.Enabled = true;
                this.rdoOldTest.Enabled = true;
            }

            Database db = new Database(this.m_DBFile);
            Query q = new Query(QueryType.SELECT, Common.TABLE_BOOK_LIST);
            q.SELECT("BookName");
            q.SELECT("Order");
            q.ORDERBY("Order", SortDirection.ASCENDING);
            db.RunQuery(q);
            this.clbBooks.Items.Clear();
            this.rdoEntireBible.Checked = true;

            for (int a = 0; a < q.RowsReturned; a++)
            {
                this.clbBooks.Items.Add(q.Results.GetFieldString(0, a), true);
            }
        }

        #endregion

        #region - Book Selection -

        /// <summary>
        /// Check all the books...
        /// </summary>
        /// <param name="sender">Radio Button</param>
        /// <param name="e">Events</param>
        private void rdoEntireBible_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rdoEntireBible.Checked)
            {
                this.SetAllBooks(true);
            }
        }

        /// <summary>
        /// Check the Old Testament books...
        /// </summary>
        /// <param name="sender">Radio Button</param>
        /// <param name="e">Events</param>
        private void rdoOldTest_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rdoOldTest.Checked)
            {
                if (this.clbBooks.Items.Count > 38)
                {
                    this.SetAllBooks(false);
                    for (int a = 0; a < 39; a++)
                    {
                        this.clbBooks.SetItemChecked(a, true);
                    }
                }
            }
        }

        /// <summary>
        /// Check the New Testament books...
        /// </summary>
        /// <param name="sender">Radio Button</param>
        /// <param name="e">Events</param>
        private void rdoNewTest_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rdoNewTest.Checked)
            {
                if (this.clbBooks.Items.Count > 40)
                {
                    this.SetAllBooks(false);
                    for (int a = 39; a < this.clbBooks.Items.Count; a++)
                    {
                        this.clbBooks.SetItemChecked(a, true);
                    }
                }
                else if (this.clbBooks.Items.Count == 27)
                {
                    // New Testament only...
                    this.SetAllBooks(false);
                    for (int a = 0; a < this.clbBooks.Items.Count; a++)
                    {
                        this.clbBooks.SetItemChecked(a, true);
                    }
                }
            }
        }

        /// <summary>
        /// UnCheck all the books...
        /// </summary>
        /// <param name="sender">Radio Button</param>
        /// <param name="e">Events</param>
        private void rdoNone_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rdoNone.Checked)
            {
                this.SetAllBooks(false);
            }
        }

        /// <summary>
        /// Checks or Unchecks all books...
        /// </summary>
        /// <param name="check">Check State</param>
        private void SetAllBooks(bool check)
        {
            for (int a = 0; a < this.clbBooks.Items.Count; a++)
            {
                this.clbBooks.SetItemChecked(a, check);
            }
        }

        #endregion

        #region - Version -

        /// <summary>
        /// Occurs when version is changed...
        /// </summary>
        /// <param name="sender">ComboBox</param>
        /// <param name="e">Events</param>
        private void m_cmbVersion_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Clear results...
            this.SetEmptyResults();

            if (this.m_cmbVersion.Text.Equals("Search " + Common.TYPE_REFERENCE))
            {
                this.m_Type = Common.TYPE_REFERENCE;
                this.rdoEntireBible.Checked = true;
                this.rdoNewTest.Visible = false;
                this.rdoOldTest.Visible = false;
                this.m_SearchInDef.Visible = true;
                this.clbBooks.Items.Clear();
                foreach (cJData.icDBInfo dbTemp in this.m_FormMain.ProgramData.ReferenceDatabases)
                {
                    this.clbBooks.Items.Add(dbTemp.Name, true);
                }
            }
            else
            {
                this.rdoNewTest.Visible = true;
                this.rdoOldTest.Visible = true;
                this.m_SearchInDef.Visible = false;

                // Update books...
                this.m_DBFile = this.m_FormMain.GetDBPath(this.m_cmbVersion.Text);
                this.UpdateBookList();
            }
        }

        /// <summary>
        /// Changes the current version...
        /// </summary>
        /// <param name="version">Version to Change to.</param>
        public void ChangeVersion (string version)
        {
            this.m_cmbVersion.SelectedIndex = this.m_cmbVersion.Items.IndexOf(version);
        }

        #endregion

        #region -= Search =-

        void SearchText_KeyDown (object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                this.m_btnSearch_Click(sender, null);
            }
        }

        private void m_btnSearch_Click(object sender, EventArgs e)
        {
            this.Search();
        }

        /// <summary>
        /// Adds the Text in the search field to the combobox...
        /// </summary>
        private void AddSearchText()
        {
            for (int a = 0; a < this.m_cmbSearch.Items.Count; a++)
            {
                if (this.m_cmbSearch.Text.Equals(this.m_cmbSearch.Items[a].ToString(), StringComparison.CurrentCultureIgnoreCase))
                {
                    return;
                }
            }

            this.m_cmbSearch.Items.Add(this.m_cmbSearch.Text);
        }

        /// <summary>
        /// Searches for the given text...
        /// </summary>
        /// <param name="text">string to search for.</param>
        public void Search(string text)
        {
            this.m_cmbSearch.Text = text;
            if (this.m_Loaded)
                this.Search();
            else
                this.m_Loaded = true;
        }

        /// <summary>
        /// Searches the selected bible for the text...
        /// </summary>
        private void Search()
        {
            this._Working.SetText("Searching for " + this.m_cmbSearch.Text.Trim() + "...");
            this._Working.Visible = true;
            this.SetEmptyResults();
            this.lblResults.Text = "0 items found.";
            if (this.m_cmbSearch.Text.Trim() != string.Empty)
            {
                this.SetTabText();
                this.AddSearchText();

                ArrayList data = new ArrayList();
                data.Add(this.clbBooks.CheckedItems);
                data.Add(this.m_cmbSearch.Text.Trim());
                data.Add(this.m_DBFile);
                if (this.rdoAll.Checked)
                    data.Add(Common.SearchCriteria.AllWords);
                else if (this.rdoAny.Checked)
                    data.Add(Common.SearchCriteria.AnyWord);
                else
                    data.Add(Common.SearchCriteria.Phrase);

				data.Add(this.m_cmbVersion.Text);
                if (this.m_Type == Common.TYPE_REFERENCE)
                {
                    Thread t = new Thread(new ParameterizedThreadStart(this.SearchReference));
                    t.Start(data);
                }
                else if (this.m_Type == Common.TYPE_BIBLE || this.m_Type == Common.TYPE_OTHER)
                {
                    Thread t = new Thread(new ParameterizedThreadStart(this.SearchBible));
                    t.Start(data);
                }
                else
                {
                    Thread t = new Thread(new ParameterizedThreadStart(this.FindPassages));
                    t.Start(data);
                }
            }
        }

        #endregion

        #region -= Find Passages =-

        /// <summary>
        /// Finds Passages...
        /// </summary>
        /// <param name="totalResults">Number of Results</param>
        /// <param name="index">Index of book</param>
        private void FindPassages (object sourceObj)
        {
            ArrayList data = sourceObj as ArrayList;
            List<cPassage> passages = cParser.Parse(data[1].ToString());
            this.m_SearchResults = new List<string[]>();
            string dbPath = "";

            if (passages.Count > 0)
            {
                CheckedListBox.CheckedItemCollection items = data[0] as CheckedListBox.CheckedItemCollection;
                foreach (string version in items)
                {
                    //string version = data[0].ToString();
                    Database db = new Database(this.m_FormMain.GetDBPath(version));
                    if (string.IsNullOrEmpty(dbPath))
                        dbPath = db.DBPath;

                    foreach (cPassage passage in passages)
                    {
                        Query q = new Query(QueryType.SELECT, passage.Book);
                        q.SELECT("Verse");
                        q.SELECT("Text");
                        q.WHERE("Chapter", Operator.EQUALS, passage.Chapter);
                        if (passage.Verse != null)
                            q.WHERE("Verse", Operator.EQUALS, passage.Verse);
                        db.RunQuery(q);

                        for (int z = 0; z < q.RowsReturned; z++)
                        {
                            this.m_SearchResults.Add(new string[] { version, passage.Book + " " + passage.Chapter + ":" +
                                            q.Results.GetFieldString(0, z), q.Results.GetFieldString(1, z) });
                        }
                    }
                }
            }

            this.m_SearchResults.Sort(new PassageRowComparer(ListSortDirection.Ascending, dbPath));
            this.GroupSearchResults(data[1].ToString());
        }

        #endregion

        #region -= Search Reference =-

        /// <summary>
        /// Searches Reference...
        /// </summary>
        /// <param name="totalResults">Number of Results</param>
        /// <param name="index">Index of book</param>
        private void SearchReference (object sourceObj)
        {
            this.m_SearchResults = new List<string[]>();
            ArrayList data = sourceObj as ArrayList;
            CheckedListBox.CheckedItemCollection items = data[0] as CheckedListBox.CheckedItemCollection;
            foreach (string source in items)
            {
                string searchText = data[1].ToString();

                string dataPath = "";
                foreach (cJData.icDBInfo dbTemp in this.m_FormMain.ProgramData.ReferenceDatabases)
                {
                    if (dbTemp.Name == source)
                    {
                        dataPath = Common.DATA_FOLDER + dbTemp.Path;
                        break;
                    }
                }

                Database db = new Database(dataPath);
                string[] tables = db.TableList.Split(';');
                foreach (string table in tables)
                {
                    if (table != Common.TABLE_BOOK_LIST && table != Common.TABLE_INFO)
                    {
                        Query q = new Query(QueryType.SELECT, table);
                        q.SELECT("Word");
                        q.SELECT("Text");
                        q.WHERE("Word", Operator.LIKE, searchText);
                        db.RunQuery(q);

                        for (int b = 0; b < q.RowsReturned; b++)
                        {
                            string text = q.Results.GetFieldString(1, b);
                            if (text.Length > 777)
                            {
                                text = text.Substring(0, 777);
                                for (int a = text.Length - 1; a >= 0; a--)
                                {
                                    if (text[a] == '<')
                                    {
                                        text = text.Substring(0, a - 1);
                                        break;
                                    }
                                    else if (text[a] == '>')
                                    {
                                        break;
                                    }
                                }
                                text += "...";
                            }

                           this.m_SearchResults.Add(new string[] { source, q.Results.GetFieldString(0, b),
                                         text });
                        }
                    }
                }
            }

            this.m_SearchResults.Sort(new RefRowComparer(ListSortDirection.Ascending));
			this.GroupSearchResults(data[1].ToString());
        }

        #endregion

        #region -= Search Bible =-

        /// <summary>
        /// Searches the Bible...
        /// </summary>
        /// <param name="totalResults">Number of Results</param>
        /// <param name="index">Index of book</param>
        /// <returns>TotalResults</returns>
        private void SearchBible (object sourceObj)
        {
            this.m_SearchResults = new List<string[]>();
            ArrayList data = sourceObj as ArrayList;
            Database db = new Database(data[2].ToString());
            CheckedListBox.CheckedItemCollection items = data[0] as CheckedListBox.CheckedItemCollection;
            foreach (string table in items)
            {
                Query q = new Query(QueryType.SELECT, table);
                q.SELECT("Chapter");
                q.SELECT("Verse");
                q.SELECT("Text");
                if ((Common.SearchCriteria)data[3] == Common.SearchCriteria.Phrase)
                    q.WHERE("Text", Operator.LIKE, data[1].ToString());

                db.RunQuery(q);

                if (q.RowsReturned > 0)
                {
                    for (int b = 0; b < q.RowsReturned; b++)
                    {
						this.m_SearchResults.Add(new string[] { table, "<a class=\"goto\" href=\"" + data[4].ToString() + "\" title=\"Goto " + table + " " + 
							q.Results.GetFieldString(0, b) + ":" + q.Results.GetFieldString(1, b) + "\">" + q.Results.GetFieldString(0, b) + ":" + 
							q.Results.GetFieldString(1, b) + "</a>", q.Results.GetFieldString(2, b) });
                    }
                }
            }
            this.m_SearchResults.Sort(new BibleRowComparer(ListSortDirection.Ascending, data[2].ToString()));
			this.GroupSearchResults(data[1].ToString());
        }

        #endregion

        #region -= Set Tab Text =-

        /// <summary>
        /// Sets the Text of the Tab...
        /// </summary>
        private void SetTabText ()
        {
            string tabText = "";
            switch (this.m_Type)
            {
                case "Reference":
                    tabText = "Reference Search";
                    break;
                case "Passage":
                    tabText = "Passage Lookup";
                    break;
                default:
                    tabText = "Search";
                    break;
            }
            if (!string.IsNullOrEmpty(this.m_cmbSearch.Text.Trim()))
            {
                tabText += " | " + this.m_cmbSearch.Text.Trim();
            }
            this.TabTitle = tabText;
        }

        #endregion

        #region -= Misc =-

        /// <summary>
        /// Delegate Method to display the number of results and finish search...
        /// </summary>
        /// <param name="results">Number of total results.</param>
        public void SetSearchResults (string searchText)
        {
            this.m_ResultCount = 1;
            StringBuilder sb = new StringBuilder();
            foreach (string[] result in this.m_SearchResults)
            {
                if (result[1].Equals("group"))
                {
                    sb.Append("<tr><th align=\"left\" colspan=\"3\" style=\"border-bottom: 2px soild black\">");
                    sb.Append(result[0]);
                    sb.Append("</th></tr>");
                }
                else
                {
                    sb.Append("<tr passage=\"" + result[0] + "|" + Common.RemoveHtml(result[1]) + "\"><td valign=\"top\" align=\"left\" style=\"color:" + 
                        ColorTranslator.ToHtml(Color.DarkSlateBlue) + ";\"><sup><em>[");
                    sb.Append(this.m_ResultCount.ToString() + "]</em></sup></td><td class=\"passage\" valign=\"top\" align=\"left\"");
                    if (this.m_SearchType == Common.TYPE_PASSAGE)
                        sb.Append(" NOWRAP>");
                    else
                        sb.Append(">");
                    sb.Append(result[1]);
                    sb.Append("</td><td>");
                    sb.Append(result[2]);
                    sb.Append("</td></tr>");
                    this.m_ResultCount++;
                }
            }
            this.m_ResultCount--;
            sb.Append("</table></div></div></body></html>");
            this.m_ResultsHTML = Common.HighlightHTML(sb.ToString(), searchText, false);
            this.Invoke(this.m_SetSearchResults);
        }

        private void SetSearchResults ()
        {
            if (!string.IsNullOrEmpty(this.m_ResultsHTML))
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(this.m_FormMain.GetHtmlHeader());
                sb.Append("<div id=\"reader\"><div id=\"readerTitles\"><table width=\"100%\"><tr><th align=\"center\" style=\"filter:progid:DXImageTransform.Microsoft.Gradient(endColorstr='#0060A5', startColorstr='#C0CFE2', gradientType='0');color:white;\">");
                sb.Append("Search Results for " + this.m_cmbSearch.Text.Trim() + "</th></tr></table></div>");
                sb.Append("<div id=\"innerReader\"><table class=\"search\" width=\"100%\">");
                sb.Append(this.m_ResultsHTML);
                this._WebSearch.HTML = sb.ToString();
                this.lblResults.Text = (this.m_ResultCount == 1) ? "1 item found." : this.m_ResultCount.ToString() + " items found.";
            }
            else
				this.SetEmptyResults();
			this._Working.Visible = false;
        }

        /// <summary>
        /// Groups the Search Results...
        /// </summary>
		private void GroupSearchResults (string searchText)
        {
            string book = "";
            int lastBook = -1;
            int itemCount = 0;
            for (int a = 0; a < this.m_SearchResults.Count; a++)
            {
                string[] result = this.m_SearchResults[a];
                if (!result[0].Equals(book))
                {
                    book = result[0];
                    string[] group = new string[3];
                    group[0] = book;
                    group[1] = "group";
                    group[2] = "";
                    this.m_SearchResults.Insert(a, group);

                    if (lastBook != -1)
                        this.m_SearchResults[lastBook][0] = this.m_SearchResults[lastBook][0] + " (" + itemCount.ToString() + ((itemCount == 1) ? " item" : " items") + ")";

                    itemCount = 0;
                    lastBook = a;
                }
                else
                {
                    itemCount++;
                }
            }
			if (lastBook != -1)
			{
				this.m_SearchResults[lastBook][0] = this.m_SearchResults[lastBook][0] + " (" + itemCount.ToString() + ((itemCount == 1) ? " item" : " items") + ")";
				this.SetSearchResults(searchText);
			}
			else
				this.Invoke(this.m_SetSearchResults);
        }

        /// <summary>
        /// Sets an Empty Result String...
        /// </summary>
        private void SetEmptyResults ()
        {
            this._WebSearch.HTML = this.m_FormMain.GetHtmlHeader() +
                "<div id=\"reader\"><div id=\"readerTitles\"></div><div id=\"innerReader\"><table width=\"100%\" height=\"100%\"><tr><th>No Results to Display</th></tr></table></div></div></body></html>";
        }

        /// <summary>
        /// Gets Additional Page Info.
        /// </summary>
        /// <returns>Page Info in string.</returns>
        public override string GetPageInfo ()
        {
            //return base.GetPageInfo();
            return this.m_SearchType.ToString();
        }

        /// <summary>
        /// A Method to update the Font...
        /// </summary>
        public void UpdateFont ()
        {
            this.SetSearchResults();
            //this.m_SearchGrid.Font = this.m_FormMain.ProgramData.DefaultFont.ToFont();
        }

        #endregion

        #region - Menu -

        /// <summary>
        /// Occurs when the context menu is opening...
        /// </summary>
        /// <param name="sender">ContextMenuStrip</param>
        /// <param name="e">CancelEventArgs</param>
        void ctxMain_Opening (object sender, CancelEventArgs e)
        {
            if (string.IsNullOrEmpty(this._WebSearch.Selection))
            {
                this.copyToolStripMenuItem.Enabled = false;
                this.searchToolStripMenuItem.Enabled = false;
                this.defineToolStripMenuItem.Enabled = false;
                this.searchToolStripMenuItem.Text = "Nothing to Search for...";
                this.defineToolStripMenuItem.Text = "Nothing to Look up...";
            }
            else
            {
                this.copyToolStripMenuItem.Enabled = true;
                this.searchToolStripMenuItem.Enabled = true;
                this.searchToolStripMenuItem.Text = "Search for " + this._WebSearch.Selection.Split(' ')[0] + "...";
                this.defineToolStripMenuItem.Enabled = true;
                this.defineToolStripMenuItem.Text = "Look up " + this._WebSearch.Selection.Split(' ')[0] + "...";
            }

            this.gotoChapterToolStripMenuItem.Enabled = false;
            this.copyItemToolStripMenuItem.Enabled = false;
            this.gotoChapterToolStripMenuItem.Text = "Nothing to Goto...";
            HtmlElementCollection hEls = this._WebSearch.Document.GetElementsByTagName("TR");
            foreach (HtmlElement hEl in hEls)
            {
                if (!string.IsNullOrEmpty(hEl.Style))
                {
                    int index = 0;
                    string passage = "";
                    if ((index = hEl.OuterHtml.IndexOf("passage=")) != -1)
                        passage = hEl.OuterHtml.Substring(index + 9, hEl.OuterHtml.IndexOf(">") - 10 - index);

                    if (!string.IsNullOrEmpty(passage))
                    {
                        this.gotoChapterToolStripMenuItem.Enabled = true;
                        this.copyItemToolStripMenuItem.Enabled = true;
                        if (passage.Contains("|"))
                        {
                            if (this.m_SearchType == Common.TYPE_BIBLE)
                                this.gotoChapterToolStripMenuItem.Text = "Goto " + passage.Replace('|', ' ') + "...";
                            else
                                this.gotoChapterToolStripMenuItem.Text = "Goto " + passage.Split('|')[1] + "...";
                        }
                        else
                        {
                            this.gotoChapterToolStripMenuItem.Text = "Goto item...";
                        }
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// Copies the selected Text...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        void Copy_Click (object sender, System.EventArgs e)
        {
            this._WebSearch.Copy();
        }

        /// <summary>
        /// Copies the selected item...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        void CopyItem_Click (object sender, System.EventArgs e)
        {
            HtmlElementCollection hEls = this._WebSearch.Document.GetElementsByTagName("TR");
            string copyText = "";
            foreach (HtmlElement hEl in hEls)
            {
                if (!string.IsNullOrEmpty(hEl.Style))
                {
                    int index = 0;
                    string passage = "";
                    if ((index = hEl.OuterHtml.IndexOf("passage=")) != -1)
                        passage = hEl.OuterHtml.Substring(index + 9, hEl.OuterHtml.IndexOf(">") - 10 - index);
                    if (!string.IsNullOrEmpty(copyText))
                        copyText += "\r\n";

                    if (!string.IsNullOrEmpty(passage))
                    {
                        switch (this.m_SearchType)
                        {
                            case Common.TYPE_BIBLE:
                                {
                                    copyText += passage.Replace('|', ' ') + " - ";
                                    copyText += hEl.Children[2].InnerText;
                                }
                                break;
                            case Common.TYPE_PASSAGE:
                                {
                                    copyText += passage + " - ";
                                    copyText += hEl.Children[2].InnerText;
                                }
                                break;
                            case Common.TYPE_REFERENCE:
                                {
                                    copyText += passage + " - ";
                                    copyText += hEl.Children[2].InnerText;
                                }
                                break;
                        }
                    }
                }
            }

            if(!string.IsNullOrEmpty(copyText))
                Clipboard.SetText(copyText);
        }

        /// <summary>
        /// Searches for the selected item...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        void Search_Click (object sender, System.EventArgs e)
        {
            if(this.m_SearchType == Common.TYPE_BIBLE)
                this.m_FormMain.Search(this.m_cmbVersion.Text, this._WebSearch.Selection, this);
            else
                this.m_FormMain.Search(this.m_FormMain.ProgramData.DefaultBible, this._WebSearch.Selection, this);
        }

        /// <summary>
        /// Defines the selected item...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        void Define_Click (object sender, System.EventArgs e)
        {
            this.m_FormMain.Search(this._WebSearch.Selection, Common.TYPE_REFERENCE, this);
        }

        /// <summary>
        /// Selects all the items...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        void SelectAll_Click (object sender, System.EventArgs e)
        {

            HtmlElementCollection hEls = this._WebSearch.Document.GetElementsByTagName("TR");
            foreach (HtmlElement hEl in hEls)
            {
                if (!hEl.FirstChild.TagName.Equals("TH"))
				{
					hEl.Style = "background: #C0CFE2;";
                }
            }
        }

        /// <summary>
        /// Goes to the selected item...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        void Goto_Click (object sender, System.EventArgs e)
        {
            HtmlElementCollection hEls = this._WebSearch.Document.GetElementsByTagName("TR");
            List<cPassage> passages = new List<cPassage>();
            foreach (HtmlElement hEl in hEls)
            {
                if (!string.IsNullOrEmpty(hEl.Style))
                {
                    int index = 0;
                    string passage = "";
                    if ((index = hEl.OuterHtml.IndexOf("passage=")) != -1)
                        passage = hEl.OuterHtml.Substring(index + 9, hEl.OuterHtml.IndexOf(">") - 10 - index);

                    if (!string.IsNullOrEmpty(passage))
                    {
                        switch (this.m_SearchType)
                        {
                            case Common.TYPE_BIBLE:
                                {
                                    if (this.m_Type == Common.TYPE_OTHER)
                                    {
                                        cPassage p = new cPassage();
                                        p.Book = passage.Split('|')[0];
                                        p.Chapter = passage.Split('|')[1].Split(':')[0];
                                        p.Verse = passage.Split('|')[1].Split(':')[1];
                                        p.Version = this.m_cmbVersion.Text;
                                        passages.Add(p);
                                    }
                                    else
                                    {
                                        List<cPassage> passes = cParser.Parse(passage.Replace('|', ' '));
                                        foreach (cPassage pass in passes)
                                            pass.Version = this.m_cmbVersion.Text;

                                        passages.AddRange(passes);
                                    }
                                }
                                break;
                            case Common.TYPE_PASSAGE:
                                {
                                    List<cPassage> passes = cParser.Parse(passage.Split('|')[1]);
                                    foreach (cPassage pass in passes)
                                        pass.Version = passage.Split('|')[0];

                                    passages.AddRange(passes);
                                }
                                break;
                            case Common.TYPE_REFERENCE:
                                {
                                    bool added = false;
                                    foreach (cPassage tempPass in passages)
                                    {
                                        if (tempPass.Version.Equals(passage.Split('|')[0]))
                                        {
                                            added = true;
                                            tempPass.Book += "|" + passage.Split('|')[1];
                                            break;
                                        }
                                    }
                                    if (!added)
                                    {
                                        cPassage pass = new cPassage();
                                        pass.Version = passage.Split('|')[0];
                                        pass.Book = passage.Split('|')[1];
                                        passages.Add(pass);
                                    }
                                }
                                break;
                        }
                    }
                }
            }

            if (this.m_SearchType == Common.TYPE_REFERENCE)
            {
                foreach (cPassage tempPass in passages)
                {
                    this.m_FormMain.StartReference(tempPass.Version, tempPass.Book.Split('|'), this);
                }
            }
            else
            {
                this.m_FormMain.StartBible(passages, this);
            }
        }

        #endregion

        private void _btnShowHide_Click (object sender, EventArgs e)
        {
            if (this._btnShowHide.ButtonText.Equals("Less"))
            {
                this._btnShowHide.ButtonText = "More";
                this.grpSearch.Height = 75;
            }
            else
            {
                this._btnShowHide.ButtonText = "Less";
                this.grpSearch.Height = 200;
            }
        }

        #region IWebberHost Members

        public bool SelectRefWord (string word, bool tryContains)
        {
			return true;
        }

        public ContextMenuStrip GetContextMenu ()
        {
            return this.ctxMain;
        }

        public string Book
        {
            get { return ""; }
        }

        public string GetVersion (int version)
        {
            return "";
        }

        public string GetVersionPath (int version)
        {
            return "";
        }

        public Jonathan.Tabber.TabberPage GetTabPage ()
        {
            return this;
        }

        #endregion
    }
}
